package com.mxpio.erp.technology.service.impl;

import com.mxpio.erp.common.enums.CommonEnums;
import com.mxpio.erp.common.enums.OrderStatusEnums;
import com.mxpio.erp.common.technology.entity.*;
import com.mxpio.erp.common.technology.service.BomInfoAuditService;
import com.mxpio.erp.common.technology.vo.AuditOpinionVO;
import com.mxpioframework.common.exception.MBootException;
import com.mxpioframework.common.util.BeanReflectionUtils;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.policy.impl.CrudType;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.ParseException;
import java.util.*;

@Service
public class BomInfoAuditServiceImpl extends BaseServiceImpl<BomInfoAudit> implements BomInfoAuditService {

    private static Date longLongDate;

    static {
        try{
            longLongDate = DateUtils.parseDate("2099-12-31","yyyy-MM-dd");
        }
        catch (ParseException ignored){

        }
    }

    @Transactional(
            readOnly = false
    )
    @Override
    public BomInfoAudit listBomAudit(String bomId){
        List<BomInfoAudit> auditList = JpaUtil.linq(BomInfoAudit.class).equal("bomId",bomId).list();
        if(CollectionUtils.isNotEmpty(auditList)){
            BomInfoAudit bomInfoAudit = auditList.get(0);
            List<BomInfoLineAudit> allLines = JpaUtil.linq(BomInfoLineAudit.class).in("bomId",bomInfoAudit.getBomId()).list();
            bomInfoAudit.setBomInfoLineList(allLines);
            return bomInfoAudit;
        }
        return null;
    }

    @Transactional(
            readOnly = false
    )
    @Override
    public Result<BomInfoAudit> updateBomStatus(BomInfoAudit bomInfoAudit, OrderStatusEnums.BomStatus bomStatus){
        bomInfoAudit.setUseType(bomStatus.getStatusCode());
        this.update(bomInfoAudit);
        return Result.OK();
    }

    @Transactional(
            readOnly = false
    )
    @Override
    public BomInfoAudit audit(BomInfoAudit audit, AuditOpinionVO auditOpinionVO){

        String agree = auditOpinionVO.getAgree();
        String auditOpinion = auditOpinionVO.getAuditOpinion();
        if(CommonEnums.YesNo.YES.getCode().equals(agree)){
            if(Objects.isNull(audit.getBeginTime())){
                throw new IllegalArgumentException("生效时间为空");
            }
            String version = "V1.0";
            BomInfo currentBomInfo = getCrrentBomInfo(audit.getParentCode());
            List<BomInfoLineAudit> bomInfoLineAuditList = JpaUtil.linq(BomInfoLineAudit.class).equal("bomId",audit.getBomId()).list();
            //查到上一个版本
            if(currentBomInfo!=null){
                Date currentBeginTime = currentBomInfo.getBeginTime();
                if(Objects.isNull(currentBeginTime)){
                    throw new IllegalArgumentException("当前版本BOM生效时间为空");
                }
                if(currentBeginTime.compareTo(audit.getBeginTime())>-1){
                    throw new IllegalArgumentException("新审核BOM生效时间必须晚于上一个版本");
                }
                version = getNextVersion(currentBomInfo.getVersion());
                //更新上一个版本数据
                currentBomInfo.setPrimaryBom("0");
                currentBomInfo.setEndTime(audit.getBeginTime());

                //处理子表
                if(CollectionUtils.isNotEmpty(bomInfoLineAuditList)){
                    for(BomInfoLineAudit lineAudit:bomInfoLineAuditList){//先处理更新和删除
                        if(CrudType.UPDATE.toString().equals(lineAudit.getTmpCrudType())){
                            invaildCurrentBomInfoLine(lineAudit.getItemCode(),audit.getParentCode(),audit.getBeginTime());
                            saveNewBomInfoLine(lineAudit,audit);
                        }
                        else if(CrudType.DELETE.toString().equals(lineAudit.getTmpCrudType())){
                            invaildCurrentBomInfoLine(lineAudit.getItemCode(),audit.getParentCode(),audit.getBeginTime());
                        }
                    }
                    for(BomInfoLineAudit lineAudit:bomInfoLineAuditList){//最后处理新增的情况 防止invaildCurrentBomInfoLine逻辑误判
                        if(CrudType.SAVE.toString().equals(lineAudit.getTmpCrudType())){
                            saveNewBomInfoLine(lineAudit,audit);
                        }
                    }
                }

            }
            else{
                //没有上一个版本，直接新增子表
                if(CollectionUtils.isNotEmpty(bomInfoLineAuditList)){
                    for(BomInfoLineAudit lineAudit:bomInfoLineAuditList){
                        if(!CrudType.SAVE.toString().equals(lineAudit.getTmpCrudType())){
                            continue;
                        }
                        saveNewBomInfoLine(lineAudit,audit);
                    }
                }
            }

            //插入新BOM表
            BomInfo newBomInfo = new BomInfo();
            try{
            	BeanReflectionUtils.copyProperties(newBomInfo,audit);
            }
            catch (Exception e){
                throw new MBootException("生成新BOM失败");
            }
            newBomInfo.setBomId(null);
            newBomInfo.setVersion(version);
            newBomInfo.setPrimaryBom("1");
            newBomInfo.setEndTime(longLongDate);
            newBomInfo.setUseType(OrderStatusEnums.BomStatus.USING.getStatusCode());
            JpaUtil.save(newBomInfo);

            //更新原BOM表
            if(currentBomInfo!=null){
                JpaUtil.update(currentBomInfo);
            }
            //变更审核状态
            audit.setUseType(OrderStatusEnums.BomStatus.USING.getStatusCode());
        }
        else{
            //变更审核状态
            audit.setUseType(OrderStatusEnums.BomStatus.VOIDED.getStatusCode());
        }
        audit.setAuditOpinion(auditOpinion);
        audit.setAgree(agree);
        JpaUtil.update(audit);

        //删除草稿
        deleteTmp(audit.getParentCode());

        return audit;

    }

    private String getNextVersion(String version){
        String versionNum = StringUtils.substring(version,1,StringUtils.indexOf(version,"."));
        return "V"+(Integer.parseInt(versionNum)+1)+".0";
    }

    private BomInfo getCrrentBomInfo(String parentCode){
        List<BomInfo> currentBomInfoList = JpaUtil.linq(BomInfo.class).equal("parentCode",parentCode).equal("primaryBom","1").list();
        if(CollectionUtils.isNotEmpty(currentBomInfoList)){
            return currentBomInfoList.get(0);
        }
        return null;
    }

    private void saveNewBomInfoLine(BomInfoLineAudit line,BomInfoAudit audit){
        BomInfoLine newBomInfoLine = new BomInfoLine();
        try{
        	BeanReflectionUtils.copyProperties(newBomInfoLine,line);
        }
        catch (Exception e){
            throw new MBootException("生成新BOM失败");
        }
        //因为是不同版本的bom公用一套bomLine，所bomId用parentCode关联
        newBomInfoLine.setBomId(audit.getParentCode());
        newBomInfoLine.setBomLineId(null);
        newBomInfoLine.setBeginTime(audit.getBeginTime());
        newBomInfoLine.setEndTime(longLongDate);
        JpaUtil.save(newBomInfoLine);
    }

    private void deleteTmp(String parentCode){
        //删草稿
        List<BomInfoTmp> bomInfoTmpList = JpaUtil.linq(BomInfoTmp.class).equal("parentCode",parentCode).list();
        if(CollectionUtils.isNotEmpty(bomInfoTmpList)){
            for(BomInfoTmp bomInfoTmp : bomInfoTmpList){
                JpaUtil.lind(BomInfoLineTmp.class).equal("bomId",bomInfoTmp.getBomId()).delete();
                JpaUtil.lind(BomInfoTmp.class).equal("bomId",bomInfoTmp.getBomId()).delete();
            }
        }
    }

    private void invaildCurrentBomInfoLine(String itemCode,String parentCode, Date endDate){
        List<BomInfoLine> list = JpaUtil.linq(BomInfoLine.class).equal("itemCode",itemCode).equal("bomId",parentCode).equal("endTime",longLongDate).list();
        if(CollectionUtils.isEmpty(list)){
            throw new MBootException("找不到itemCode{"+itemCode+"}的上一个版本BomLine");
        }
        if(list.size()>1){
            throw new MBootException("找到多个itemCode{"+itemCode+"}的上一个版本BomLine");
        }
        BomInfoLine bomInfoLine = list.get(0);

        bomInfoLine.setEndTime(endDate);
        JpaUtil.update(bomInfoLine);
    }

}
